function pco_rec2file_swtrig(imacount)
%
%   pco_rec2file_swtrig(imacount)
%
%	* Input parameters :
%                  imacount
%	* Output parameters :
%
%records and saves to disk 'imacount' images
%the actual setup of the camera is used, with the fiollowing modifications
%storage mode is set to STORAGE_MODE_FIFO
%recorder submode is set to RECORDER_SUBMODE_RINGBUFFER
%trigger mode is set to SOFTWARE_TRIGGER
%
%function workflow
%parameters are checked
%camera parameters are set
%camera is armed
%camera is started
%memory for one image is allocated
%
%the function does the following loop until imacount  images are done
%
%control external components
%send force trigger, one image is done
%wait until image is in camera memory
%get image from camera
%save image to disk
%
%free allocated memory
%stop camera

glvar=struct('do_libunload',0,'do_close',0,'camera_open',0,'out_ptr',[]);

if(~exist('imacount','var'))
 imacount = 1;   
end

[err,glvar]=pco_camera_setup(glvar,0);
if(err~=0)
 disp(['pco_camera_setup failed with error ',num2str(err,'%X')]);   
 return;
end

disp(['camera_open should be 1 is ',int2str(glvar.camera_open)]);

out_ptr=glvar.out_ptr;   

%test camera recording state and stop camera, if camera is recording
act_recstate = uint16(0); 
[errorCode,out_ptr,act_recstate] = calllib('PCO_CAM_SDK', 'PCO_GetRecordingState', out_ptr,act_recstate);
if(errorCode)
 disp(['PCO_GetRecordingState failed with error ',num2str(errorCode,'%X')]);   
end

if(act_recstate~=0)
 [errorCode,out_ptr] = calllib('PCO_CAM_SDK', 'PCO_SetRecordingState', out_ptr, 0);
 if(errorCode)
  disp(['PCO_SetRecordingState failed with error ',num2str(errorCode,'%X')]);   
 end    
end

%set STORAGE_MODE_FIFO
[errorCode,out_ptr] = calllib('PCO_CAM_SDK', 'PCO_SetStorageMode', out_ptr,1);
if(errorCode)
 disp(['PCO_SetStorageMode failed with error ',num2str(errorCode,'%X')]);   
end

%set RECORDER_SUBMODE_RINGBUFFER
[errorCode,out_ptr] = calllib('PCO_CAM_SDK', 'PCO_SetRecorderSubmode', out_ptr,1);
if(errorCode)
 dsip(['PCO_SetRecorderSubmode failed with error ',num2str(errorCode,'%X')]);   
end

%set TRIGGER_MODE_SOFTWARETRIGGER
[errorCode,out_ptr] = calllib('PCO_CAM_SDK', 'PCO_SetTriggerMode', out_ptr,1);
if(errorCode)
 disp(['PCO_SetTriggerMode failed with error ',num2str(errorCode,'%X')]);   
end

[errorCode,out_ptr] = calllib('PCO_CAM_SDK', 'PCO_ArmCamera', out_ptr);
if(errorCode)
 disp(['PCO_ArmCamera failed with error ',num2str(errorCode,'%X')]);   
end

[errorCode] = calllib('PCO_CAM_SDK', 'PCO_SetRecordingState', out_ptr, 1);
if(errorCode)
 disp(['PCO_SetRecordingState failed with error ',num2str(errorCode,'%X')]);   
end    

%declare some variables and get some information from camera
dwValidImageCnt=uint32(0);
dwMaxImageCnt=uint32(0);
wtrigdone=uint16(0);
dwSec=uint32(0);
dwNanoSec=uint32(0);

ml_cam_desc.wSize=uint16(436);
cam_desc=libstruct('PCO_Description',ml_cam_desc);
[errorCode,out_ptr,cam_desc] = calllib('PCO_CAM_SDK', 'PCO_GetCameraDescription', out_ptr,cam_desc);
if(errorCode)
 disp(['PCO_GetCameraDescription failed with error ',num2str(errorCode,'%08X')]);   
end
bitpix=uint16(cam_desc.wDynResDESC);

ml_cam_type.wSize=uint16(1364);
cam_type=libstruct('PCO_CameraType',ml_cam_type);
[errorCode,out_ptr,cam_type] = calllib('PCO_CAM_SDK', 'PCO_GetCameraType', out_ptr,cam_type);
if(errorCode)
 disp(['PCO_GetCameraType failed with error ',num2str(errorCode,'%08X')]);   
end
interface=uint16(cam_type.wInterfaceType);



%get time in ms, which is used for one image
[errorCode,out_ptr,dwSec,dwNanoSec] = calllib('PCO_CAM_SDK', 'PCO_GetCOCRuntime', out_ptr,dwSec,dwNanoSec);
if(errorCode)
 disp(['PCO_GetCOCRuntime failed with error ',num2str(errorCode,'%X')]);   
end

waittime_s = double(dwNanoSec);
waittime_s = waittime_s / 1000000000;
waittime_s = waittime_s + double(dwSec);

act_segment = uint16(0); 
[errorCode,out_ptr,act_segment] = calllib('PCO_CAM_SDK', 'PCO_GetActiveRamSegment', out_ptr,act_segment);
if(errorCode)
 disp(['PCO_GetActiveRamSegment failed with error ',num2str(errorCode,'%08X')]);   
 return;
end

disp(['Active Segment ',int2str(act_segment)]);

act_align = uint16(0); 
[errorCode,out_ptr,act_align] = calllib('PCO_CAM_SDK', 'PCO_GetBitAlignment', out_ptr,act_align);
if(errorCode)
 disp(['PCO_GetBitAlignment failed with error ',num2str(errorCode,'%08X')]);   
 return;
end
disp(['Actual Alignment ',int2str(act_align)]);

ml_strSegment.wSize=uint16(108);
strSegment=libstruct('PCO_Segment',ml_strSegment);
[errorCode,out_ptr,strSegment] = calllib('PCO_CAM_SDK', 'PCO_GetSegmentStruct', out_ptr,act_segment,strSegment);
if(errorCode)
 disp(['PCO_GetSegmentStruct failed with error ',num2str(errorCode,'%08X')]);   
 return;
end
disp(['Segmentstruct XRes ',int2str(strSegment.wXRes),'  YRes ',int2str(strSegment.wYRes)]);

[errorCode,out_ptr]  = calllib('PCO_CAM_SDK', 'PCO_CamLinkSetImageParameters', out_ptr,strSegment.wXRes,strSegment.wYRes);
if(errorCode)
 disp(['PCO_CamLinkSetImageParameters failed with error ',num2str(errorCode,'%08X')]);   
 return;
end

%get the memory for the image
%need special code for firewire interface

imas=uint32(fix((double(bitpix)+7)/8));
imas= imas*uint32(strSegment.wYRes)* uint32(strSegment.wXRes); 
imasize=imas;

if(interface==1)
  i=floor(double(imas)/4096);
  i=i+1;
  i=i*4096;
  imasize=i;
  i=i-double(imas);
  xs=uint32(fix((double(bitpix)+7)/8));
  xs=xs*strSegment.wXRes;
  i=floor(i/double(xs));
  i=i+1;
  lineadd=i;
 disp(['imasize is: ',int2str(imas),' aligned: ',int2str(imasize)]); 
 disp([int2str(lineadd),' additional lines have been allocated ']);   
else
 lineadd=0;   
end

image_stack=ones(strSegment.wXRes,strSegment.wYRes+lineadd,'uint16');

sBufNr=int16(-1);
im_ptr = libpointer('uint16Ptr',image_stack);
ev_ptr = libpointer('voidPtr');

[errorCode,out_ptr,sBufNr,image_stack,ev_ptr]  = calllib('PCO_CAM_SDK','PCO_AllocateBuffer', out_ptr,sBufNr,imasize,im_ptr,ev_ptr);
if(errorCode)
 disp(['PCO_AllocateBuffer failed with error ',num2str(errorCode,'%08X')]);   
 return;
end

%here is the loop

for n=1:imacount
 save_file=sprintf('test_%04d.tif',n);

%control external components
%next line simulates control call
 pause(0.500);

 [errorCode,out_ptr,wtrigdone] = calllib('PCO_CAM_SDK', 'PCO_ForceTrigger', out_ptr,wtrigdone);
 if(errorCode)
  disp(['PCO_ForceTrigger failed with error ',num2str(errorCode,'%X')]);   
 end
 
 dwValidImageCnt=0;
 a=0;
 while((dwValidImageCnt<1)&&(errorCode==0))
  [errorCode,out_ptr,dwValidImageCnt,dwMaxImageCnt]  = calllib('PCO_CAM_SDK', 'PCO_GetNumberOfImagesInSegment', out_ptr,act_segment,dwValidImageCnt,dwMaxImageCnt);
  if(errorCode)
   disp(['PCO_GetNumberOfImagesInSegment failed with error ',num2str(errorCode,'%X')]);   
  end
  disp(['segment ',int2str(act_segment),':  valid images: ',int2str(dwValidImageCnt),' max images ',int2str(dwMaxImageCnt)]);
  pause(waittime_s);
  a=a+1;
  if(a>10)
   disp('timeout in waiting for images');   
   errorCode=1;
  end
 end

 if(errorCode==0)
  [errorCode,out_ptr]  = calllib('PCO_CAM_SDK','PCO_GetImageEx',out_ptr,act_segment,0,0,sBufNr,strSegment.wXRes,strSegment.wYRes,bitpix);
  if(errorCode)
   disp(['PCO_GetImageEx failed with error ',num2str(errorCode,'%08X')]);   
  else
   disp(['PCO_GetImageEx image ' int2str(n) ' done']);
  end
 end

 if(errorCode==0)
  [errorCode,out_ptr,image_stack]  = calllib('PCO_CAM_SDK','PCO_GetBuffer',out_ptr,sBufNr,im_ptr,ev_ptr);
  if(errorCode)
   disp(['PCO_GetBuffer failed with error ',num2str(errorCode,'%08X')]);   
  end
 end

 result_image=image_stack;
 if(errorCode==0)
  for i=1:lineadd
   result_image(:,end)=[];
  end
  imshow(result_image',[0,8000]);
  imwrite(result_image',fullfile('.',save_file),'tif','Compression','none');
 else
  break;
 end
end   

errorCode  = calllib('PCO_CAM_SDK','PCO_FreeBuffer',out_ptr,sBufNr);
if(errorCode)
 disp(['PCO_FreeBuffer failed with error ',num2str(errorCode,'%08X')]);   
end

disp('Press "Enter" to close window and camera SDK')
pause();

close();
clear image_stack;
clear result_image;

[errorCode] = calllib('PCO_CAM_SDK', 'PCO_SetRecordingState', out_ptr, 0);
if(errorCode)
 disp(['PCO_SetRecordingState failed with error ',num2str(errorCode,'%X')]);   
end    

if(glvar.camera_open==1)
 glvar.do_close=1;
% glvar.do_libunload=1;
 pco_camera_open_close(glvar);
end   

clear glvar;

end
   

